/**
 * 
 */
package com.taobao.api.extra;

import static com.taobao.api.ApiConstants.ANONS;
import static com.taobao.api.ApiConstants.END_CREATED;
import static com.taobao.api.ApiConstants.FIELDS;
import static com.taobao.api.ApiConstants.NICK;
import static com.taobao.api.ApiConstants.ORDER_BY;
import static com.taobao.api.ApiConstants.PAGE_NO;
import static com.taobao.api.ApiConstants.PAGE_SIZE;
import static com.taobao.api.ApiConstants.START_CREATED;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.taobao.api.json.*;
import com.taobao.api.TaobaoApiException;
import com.taobao.api.TaobaoJsonRestClient;
import com.taobao.api.extra.model.CatStat;
import com.taobao.api.extra.model.CatStatsGetRequest;
import com.taobao.api.extra.model.CatStatsGetResponse;
import com.taobao.api.extra.model.ItemStat;
import com.taobao.api.extra.model.ItemStatsGetRequest;
import com.taobao.api.extra.model.ItemStatsGetResponse;
import com.taobao.api.extra.model.TbqlQueryResponse;
import com.taobao.api.extra.model.TradeStat;
import com.taobao.api.extra.model.TradeStatsGetRequest;
import com.taobao.api.extra.model.TradeStatsGetResponse;
import com.taobao.api.model.TaobaoResponse;
import com.taobao.api.util.DateUtil;

/**
 * @version 2008-11-7
 * @author ruowang
 * 
 */
public class TaobaoExtraJsonRestClient extends TaobaoJsonRestClient implements
		TaobaoExtraRestClient {
	private static final String TRADE_STATS = "trade_stats";
	private static final String CAT_STATS = "cat_stats";
	private static final String ITEM_STATS = "item_stats";
	// common应用级参数(也是销售统计的参数)
	private static final String CREATED = "created";// 销售统计时间
	private static final String ITEM_NUM = "item_num"; // 销售的商品数量
	private static final String VOLUME = "volume"; // 销售金额 如：888.88
	// 商品类目统计应用级参数
	private static final String CID = "cid"; // 后台商品标准类目id
	private static final String CAT_NAME = "cat_name"; // 类目名称
	private static final String PERCENT = "percent"; // 本类目所占销售额比率 ，如：0.02

	// 商品统计应用级参数
	private static final String IID = "iid"; // 商品id
	private static final String ITEM_TITLE = "item_title"; // 商品标题
	private static final String ITEM_PIC_PATH = "item_pic_path"; // 商品图片连接

	private static final String QUERY = "query"; // tbql查询参数

	private static final String SERVICE_URL = "http://api.taobao.com/router/rest";

	public TaobaoExtraJsonRestClient(String appkey, String secret)
			throws TaobaoApiException {
		this(SERVICE_URL, appkey, secret);
	}

	public TaobaoExtraJsonRestClient(String serviceUrl, String appkey,
			String secret) throws TaobaoApiException {
		super(serviceUrl, appkey, secret);
	}

	public TaobaoExtraJsonRestClient(String serviceUrl, String version,
			String appkey, String secret) throws TaobaoApiException {
		super(serviceUrl, version, appkey, secret);
	}

	public TaobaoExtraJsonRestClient(String appkey, String secret,
			boolean isSandbox) throws TaobaoApiException {
		super(appkey, secret, isSandbox);
	}

	/**
	 * 将返回的JsonArray转换为List<TradeStat>
	 * 
	 * @param jsonArray
	 * @param Json数组
	 * @return List<code><</code>TradeStatistics>
	 * @throws JSONException
	 * @throws ParseException
	 * @throws TaobaoApiException
	 */
	private List<TradeStat> convertJsonArrayToTradeStatisticsList(
			JSONArray jsonArray) throws JSONException, ParseException {
		List<TradeStat> getTradeStatisticsList = new ArrayList<TradeStat>();
		for (int i = 0; i < jsonArray.length(); i++) {
			TradeStat TradeStatistics = converJsonToTradeStatistics(jsonArray
					.getJSONObject(i));
			getTradeStatisticsList.add(TradeStatistics);
		}
		return getTradeStatisticsList;
	}

	/**
	 * 将返回的Json转换为TradeStat
	 * 
	 * @param json
	 * @param JSONObject
	 * @return TradeStatistics
	 * @throws ParseException
	 * @throws TaobaoApiException
	 */
	private TradeStat converJsonToTradeStatistics(JSONObject json)
			throws JSONException, ParseException {
		TradeStat newTradeStatistics = new TradeStat();
		if (json.has(CREATED)) {
			newTradeStatistics.setCreated(DateUtil.strToDate(json
					.getString(CREATED)));
		}
		if (json.has(ITEM_NUM)) {
			newTradeStatistics.setItemNum(Integer.parseInt(json
					.getString(ITEM_NUM)));
		}
		if (json.has(VOLUME)) {
			newTradeStatistics.setVolume(json.getString(VOLUME));
		}
		if (json.has(ANONS)) {
			JSONArray anons = json.getJSONArray(ANONS);
			for (int i = 0; i < anons.length(); i++) {
				newTradeStatistics.addAnon(anons.get(i));
			}
		}
		return newTradeStatistics;
	}

	/**
	 * 数据准备，将tradeStatRequest数据封装为Map对象返回
	 * 
	 * @param TradeStatsGetRequest
	 * @return Map<String, Object>
	 * @throws
	 */
	protected Map<String, Object> prepareTradeStat(
			TradeStatsGetRequest tradeStatRequest) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put(FIELDS, tradeStatRequest.getFields());
		params.put(START_CREATED, tradeStatRequest.getStartCreated());
		params.put(END_CREATED, tradeStatRequest.getEndCreated());
		params.put(PAGE_NO, tradeStatRequest.getPageNo());
		params.put(PAGE_SIZE, tradeStatRequest.getPageSize());
		params.put(ORDER_BY, tradeStatRequest.getOrderBy());
		params.put(NICK, tradeStatRequest.getNick());
		return params;
	}

	/**
	 * 发送请求将Map对象与sessionId传入,返回TradeStatsGetResponse
	 * 
	 * @param Map
	 *            <String, Object>
	 * @param sessionId
	 * @return TradeStatsGetResponse
	 * @throws TaobaoApiException
	 */
	protected TradeStatsGetResponse sendTradeStat(Map<String, Object> params,
			String sessionId) throws TaobaoApiException {
		TaobaoResponse response = getFetch().fetch(
				this.getServiceUrl(),
				getTemplateRequest(TaobaoExtraApiMethod.STAT_TRADE_GET
						.getMethod(), sessionId, params));

		TradeStatsGetResponse tradeStatisticsGetResponse = new TradeStatsGetResponse(
				response);
		// 平台访问成功
		if (tradeStatisticsGetResponse.isSuccess()) {
			JSONObject json;
			try {
				json = new JSONObject(tradeStatisticsGetResponse.getBody());
				parseError(tradeStatisticsGetResponse, json);
				// 访问淘宝成功
				if (tradeStatisticsGetResponse.isSuccess()) {
					// 对返回结果进行处理
					JSONObject rsp = getRsp(json);
					if (rsp.has(TRADE_STATS)) {
						JSONArray trade_stat = rsp.getJSONArray(TRADE_STATS);
						tradeStatisticsGetResponse
								.setTradeStats(convertJsonArrayToTradeStatisticsList(trade_stat));
					}
					setTotalResults(rsp, tradeStatisticsGetResponse);
				}
			} catch (Exception e) {
				throw new TaobaoApiException(e);
			}
		}
		return tradeStatisticsGetResponse;
	}

	/**
	 * tradeStat扩展隐私接口实现
	 * 
	 * @param TradeStatsGetRequest
	 * @param sessionId
	 * @return TradeStatsGetResponse
	 * @throws TaobaoApiException
	 */
	public TradeStatsGetResponse tradeStatGet(
			TradeStatsGetRequest tradeStatRequest, String sessionId)
			throws TaobaoApiException {
		Map<String, Object> params = prepareTradeStat(tradeStatRequest);// 封装request数据
		return sendTradeStat(params, sessionId);// 发送请求，返回TradeStatsGetResponse
	}

	/**
	 * 将返回的JsonArray转换为List<CatStat>
	 * 
	 * @param jsonArray
	 * @param Json数组
	 * @return List<code><</code>TradeStatistics>
	 * @throws TaobaoApiException
	 */
	private List<CatStat> convertJsonArrayToCatStatisticsList(
			JSONArray jsonArray) {
		List<CatStat> getCatStatisticsList = new ArrayList<CatStat>();
		CatStat CatStatistics = null;
		for (int i = 0; i < jsonArray.length(); i++) {
			CatStatistics = new CatStat();
			try {
				CatStatistics = converJsonToCatStatistics(jsonArray
						.getJSONObject(i));
			} catch (JSONException e) {
				e.printStackTrace();
			}
			getCatStatisticsList.add(CatStatistics);
		}
		return getCatStatisticsList;
	}

	/**
	 * 将返回的Json转换为CatStat
	 * 
	 * @param json
	 * @param JSONObject
	 * @return TradeStatistics
	 * @throws TaobaoApiException
	 */
	private CatStat converJsonToCatStatistics(JSONObject json)
			throws JSONException {
		CatStat newCatStatistics = new CatStat();
		if (json.has(CREATED)) {
			try {
				newCatStatistics.setCreated(DateUtil.strToDate(json
						.getString(CREATED)));
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		if (json.has(ITEM_NUM)) {
			newCatStatistics.setItemNum(Integer.parseInt(json
					.getString(ITEM_NUM)));
		}
		if (json.has(VOLUME)) {
			newCatStatistics.setVolume(json.getString(VOLUME));
		}
		if (json.has(CID)) {
			newCatStatistics.setCid(json.getString(CID));
		}
		if (json.has(CAT_NAME)) {
			newCatStatistics.setCatName(json.getString(CAT_NAME));
		}
		if (json.has(PERCENT)) {
			newCatStatistics.setPercent(json.getString(PERCENT));
		}
		return newCatStatistics;
	}

	/**
	 * 数据准备，将catStatRequests数据封装为Map对象返回
	 * 
	 * @param CatStatsGetRequest
	 * @return Map<String, Object>
	 * @throws
	 */
	protected Map<String, Object> prepareCatStat(
			CatStatsGetRequest catStatRequest) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put(FIELDS, catStatRequest.getFields());
		params.put(START_CREATED, catStatRequest.getStartCreated());
		params.put(END_CREATED, catStatRequest.getEndCreated());
		params.put(PAGE_NO, catStatRequest.getPageNo());
		params.put(PAGE_SIZE, catStatRequest.getPageSize());
		params.put(ORDER_BY, catStatRequest.getOrderBy());
		params.put(NICK, catStatRequest.getNick());
		return params;
	}

	/**
	 * 发送请求将Map对象与sessionId传入,返回CatStatsGetResponse
	 * 
	 * @param Map
	 *            <String, Object>
	 * @param sessionId
	 * @return TradeStatsGetResponse
	 * @throws TaobaoApiException
	 */
	protected CatStatsGetResponse sendCatStat(Map<String, Object> params,
			String sessionId) throws TaobaoApiException {
		TaobaoResponse response = getFetch().fetch(
				this.getServiceUrl(),
				getTemplateRequest(TaobaoExtraApiMethod.STAT_CATEGORY_GET
						.getMethod(), sessionId, params));

		CatStatsGetResponse catStatsGetResponse = new CatStatsGetResponse(
				response);
		// 平台访问成功
		if (catStatsGetResponse.isSuccess()) {
			JSONObject json;
			try {
				json = new JSONObject(catStatsGetResponse.getBody());
				parseError(catStatsGetResponse, json);
				// 访问淘宝成功
				if (catStatsGetResponse.isSuccess()) {
					// 对返回结果进行处理
					JSONObject rsp = getRsp(json);
					if (rsp.has(CAT_STATS)) {
						JSONArray cat_stat = rsp.getJSONArray(CAT_STATS);
						catStatsGetResponse
								.setCatStats(convertJsonArrayToCatStatisticsList(cat_stat));
					}
					setTotalResults(rsp, catStatsGetResponse);
				}
			} catch (JSONException e) {
				throw new TaobaoApiException(e);
			}
		}
		return catStatsGetResponse;
	}

	/**
	 * catStat扩展隐私接口实现
	 * 
	 * @param CatStatsGetRequest
	 * @param sessionId
	 * @return CatStatsGetResponse
	 * @throws TaobaoApiException
	 */
	public CatStatsGetResponse catStatGet(CatStatsGetRequest catStatRequest,
			String sessionId) throws TaobaoApiException {
		Map<String, Object> params = prepareCatStat(catStatRequest);// 封装request数据
		return sendCatStat(params, sessionId);// 发送请求，返回TradeStatsGetResponse
	}

	/**
	 * 将返回的JsonArray转换为List<CatStat>
	 * 
	 * @param jsonArray
	 * @param Json数组
	 * @return List<code><</code>TradeStatistics>
	 * @throws ParseException
	 * @throws JSONException
	 * @throws TaobaoApiException
	 */
	private List<ItemStat> convertJsonArrayToItemStatisticsList(
			JSONArray jsonArray) throws JSONException, ParseException {
		List<ItemStat> getItemStatisticsList = new ArrayList<ItemStat>();
		ItemStat ItemStatistics = null;
		for (int i = 0; i < jsonArray.length(); i++) {
			ItemStatistics = converJsonToItemStatistics(jsonArray
					.getJSONObject(i));
			getItemStatisticsList.add(ItemStatistics);
		}
		return getItemStatisticsList;
	}

	/**
	 * 将返回的Json转换为CatStat
	 * 
	 * @param json
	 * @param JSONObject
	 * @return TradeStatistics
	 * @throws ParseException
	 * @throws TaobaoApiException
	 */
	private ItemStat converJsonToItemStatistics(JSONObject json)
			throws JSONException, ParseException {
		ItemStat newItemStatistics = new ItemStat();
		if (json.has(CREATED)) {
			newItemStatistics.setCreated(DateUtil.strToDate(json
					.getString(CREATED)));
		}
		if (json.has(ITEM_NUM)) {
			newItemStatistics.setItemNum(Integer.parseInt(json
					.getString(ITEM_NUM)));
		}
		if (json.has(VOLUME)) {
			newItemStatistics.setVolume(json.getString(VOLUME));
		}
		if (json.has(IID)) {
			newItemStatistics.setIid(json.getString(IID));
		}
		if (json.has(ITEM_TITLE)) {
			newItemStatistics.setItemTitle(json.getString(ITEM_TITLE));
		}
		if (json.has(ITEM_PIC_PATH)) {
			newItemStatistics.setItemPicPath(json.getString(ITEM_PIC_PATH));
		}
		return newItemStatistics;
	}

	/**
	 * 数据准备，将itemStatRequest数据封装为Map对象返回
	 * 
	 * @param ItemStatsGetRequest
	 * @return Map<String, Object>
	 * @throws
	 */
	protected Map<String, Object> prepareItemStat(
			ItemStatsGetRequest itemStatRequest) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put(FIELDS, itemStatRequest.getFields());
		params.put(START_CREATED, itemStatRequest.getStartCreated());
		params.put(END_CREATED, itemStatRequest.getEndCreated());
		params.put(PAGE_NO, itemStatRequest.getPageNo());
		params.put(PAGE_SIZE, itemStatRequest.getPageSize());
		params.put(ORDER_BY, itemStatRequest.getOrderBy());
		params.put(NICK, itemStatRequest.getNick());
		return params;
	}
	
	
	/**
	 * 发送请求将Map对象与sessionId传入,返回RespotradeStatRequest @param Map<String, Object>
	 * 
	 * @param sessionId
	 * @return TradeStatsGetResponse
	 * @throws TaobaoApiException
	 */
	protected ItemStatsGetResponse sendItemStat(Map<String, Object> params,
			String sessionId) throws TaobaoApiException {
		TaobaoResponse response = getFetch().fetch(
				this.getServiceUrl(),
				getTemplateRequest(TaobaoExtraApiMethod.STAT_ITEM_GET
						.getMethod(), sessionId, params));

		ItemStatsGetResponse itemStatsGetResponse = new ItemStatsGetResponse(
				response);
		// 平台访问成功
		if (itemStatsGetResponse.isSuccess()) {
			JSONObject json;
			try {
				json = new JSONObject(itemStatsGetResponse.getBody());
				parseError(itemStatsGetResponse, json);
				// 访问淘宝成功
				if (itemStatsGetResponse.isSuccess()) {
					// 对返回结果进行处理
					JSONObject rsp = getRsp(json);
					if (rsp.has(ITEM_STATS)) {
						JSONArray item_stat = rsp.getJSONArray(ITEM_STATS);
						itemStatsGetResponse
								.setItemStats(convertJsonArrayToItemStatisticsList(item_stat));
					}
					setTotalResults(rsp, itemStatsGetResponse);
				}
			} catch (Exception e) {
				throw new TaobaoApiException(e);
			}
		}
		return itemStatsGetResponse;
	}

	@SuppressWarnings("unchecked")
	protected TbqlQueryResponse sendTbqlQuery(Map<String, Object> params,
			String sessionId) throws TaobaoApiException {
		TaobaoResponse response = getFetch().fetch(
				this.getServiceUrl(),
				getTemplateRequest(TaobaoExtraApiMethod.TBQL_QUERY.getMethod(),
						sessionId, params));
		TbqlQueryResponse tbqlRsp = new TbqlQueryResponse(response);
		// 平台访问成功
		if (tbqlRsp.isSuccess()) {
			JSONObject json;
			try {
				json = new JSONObject(tbqlRsp.getBody());
				parseError(tbqlRsp, json);
				// 访问淘宝成功
				if (tbqlRsp.isSuccess()) {
					// 对返回结果进行处理
					JSONObject rsp = getRsp(json);
					// TODO 其他类型的还没编写
					if (rsp.has(TRADE_STATS)) {
						JSONArray trade_stat = rsp.getJSONArray(TRADE_STATS);
						tbqlRsp
								.setRows((List) convertJsonArrayToTradeStatisticsList(trade_stat));
					}
				}
			} catch (Exception e) {
				throw new TaobaoApiException(e);
			}
		}
		return tbqlRsp;
	}

	protected Map<String, Object> prepareTbqlQuery(String tbql) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put(QUERY, tbql);
		return params;
	}

	/**
	 * itemStat扩展隐私接口实现
	 * 
	 * @param ItemStatsGetRequest
	 * @param sessionId
	 * @return ItemStatsGetResponse
	 * @throws TaobaoApiException
	 */
	public ItemStatsGetResponse itemStatGet(
			ItemStatsGetRequest itemStatRequest, String sessionId)
			throws TaobaoApiException {
		Map<String, Object> params = prepareItemStat(itemStatRequest);// 封装request数据
		return sendItemStat(params, sessionId);// 发送请求，返回TradeStatsGetResponse
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.taobao.api.extra.TaobaoExtraApi#tbql(java.lang.String,
	 * java.lang.String)
	 */
	public TbqlQueryResponse tbql(String tbql, String sessionId)
			throws TaobaoApiException {
		Map<String, Object> params = prepareTbqlQuery(tbql);// 封装request数据
		return sendTbqlQuery(params, sessionId);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.taobao.api.extra.TaobaoExtraApi#tbql(java.lang.String)
	 */
	public TbqlQueryResponse tbql(String tbql) throws TaobaoApiException {
		return tbql(tbql, null);
	}

}
